/*
 * MainWindow.cpp
 *
 *  Created on: Oct 25, 2012
 *      Author: johnny
 */

#include "MainWindow.h"
#include <QDesktopWidget>

#include <boost/format.hpp>

#include <qdialog.h>
#include <qaction.h>
#include <qdir.h>
#include <qfiledialog.h>
#include <QtUiTools/quiloader.h>

#include "../MeasWorld.h"
#include "../ConfigurationManager.h"
#include "../UserSettings.h"

namespace ui {

MainWindow::MainWindow(): BaseUI(), errLog(NULL), cfgMgrDiag(NULL) {
}

MainWindow::~MainWindow() {
    if(errLog != NULL) {
        errLog->getWidget()->close();
        delete errLog;
    }

    if(cfgMgrDiag != NULL) {
        cfgMgrDiag->getWidget()->close();
        delete cfgMgrDiag;
    }
}

bool MainWindow::setup() {
    if(!BaseUI::setup(UI_MAIN_WINDOW))
        return false;

    if(errLog == NULL) {
        errLog = new ErrorLogDialog(formWidget);
        if(!errLog->setup()) {
            core::Logger::getInstance().add(core::Error, "Error loading ErrorLog dialog");
            return false;
        }

        core::Logger::getInstance().addObserver(errLog);
        core::Logger::getInstance().addObserver(this);
    }

    // set to center screen position
    const QPoint screen = QDesktopWidget().availableGeometry(0).center();
    formWidget->move(screen - formWidget->rect().center());

	// setup events
	QAction* actExit	= formWidget->findChild<QAction*>("actionExit");
	QAction* actAbout	= formWidget->findChild<QAction*>("actionAbout");
	QAction* actCfgMgr	= formWidget->findChild<QAction*>("actionConfigurationManager");
    QAction* actErrLog  = formWidget->findChild<QAction*>("actionErrorLog");

    lcdWarnings         = formWidget->findChild<QLCDNumber*>("lcdWarnings");
    lcdErrors           = formWidget->findChild<QLCDNumber*>("lcdErrors");
    lcdAlerts           = formWidget->findChild<QLCDNumber*>("lcdAlerts");

	QObject::connect(actExit, SIGNAL(triggered()), this, SLOT(onExit()));
	QObject::connect(actAbout, SIGNAL(triggered()), this, SLOT(onAbout()));
	QObject::connect(actCfgMgr, SIGNAL(triggered()), this, SLOT(onCfgMgr()));
    QObject::connect(actErrLog, SIGNAL(triggered()), this, SLOT(onErrLog()));

    evtFilter = new MainWindowEventFilter(this);
    formWidget->installEventFilter(evtFilter);

	formWidget->setWindowTitle(APP_TITLE);
	formWidget->show();

	WelcomeDialog wd(formWidget);

	if(!wd.setup())
		return false;

	QDialog* diag = static_cast<QDialog*>(wd.getWidget());
    if(diag->exec()) {
		switch (wd.getSelectedAction()) {
            case SelectCfg:
                {
                const std::string cfgDir = util::getDirAsString(
                            util::CfgDir);
                QString fileName = QFileDialog::getOpenFileName(formWidget, "Open Configuration", QString::fromStdString(cfgDir));
                if(!fileName.isNull()) {
                    core::ConfigurationManager::getInstance().loadCfg(fileName.toStdString());
                }
                }
				break;
			case OpenCfgMgr:
                onCfgMgr();
				break;
			case OpenPrev:
                std::string prevCfgPath = wd.getPrevCfgPath();
				if(!prevCfgPath.empty())
					core::ConfigurationManager::getInstance().loadCfg(prevCfgPath);
				break;
		}
	}

	return true;
}

void MainWindow::onExit() {
    core::MeasWorld::getInstance().close();
    formWidget->close();
}

void MainWindow::onAbout() {
    AboutDialog about(formWidget);
    QDialog* diag = static_cast<QDialog*>(about.getWidget());
    diag->setWindowFlags(Qt::Dialog);
    diag->exec();
}

void MainWindow::onCfgMgr() {
    if(cfgMgrDiag == NULL) // first construct
        cfgMgrDiag = new ConfigurationManagerDialog(formWidget);

    if(!cfgMgrDiag->setup()) {
        core::Logger::getInstance().add(core::Alert, "Failed to open Configuration Manager");
        return;
    }

    QDialog *diag = static_cast<QDialog*>(cfgMgrDiag->getWidget());
    diag->exec();
}

void MainWindow::onErrLog() {
    errLog->getWidget()->setVisible(!errLog->getWidget()->isVisible());
}

void MainWindow::update(patterns::Observable * /*obs*/, void *msg) {
    QLCDNumber *lcd;
    std::string color = "background-color: ";
    core::LogEntry *entry = static_cast<core::LogEntry*>(msg);

    if(entry->message == L"INIT") {
        ;
    } else {
        switch(entry->type) {
        case core::Warning:
            lcd = lcdWarnings;
            color += "rgb(255, 255, 0);";
            break;
        case core::Error:
            lcd = lcdErrors;
            color += "rgb(255, 0, 0);";
            break;
        case core::Alert:
            lcd = lcdAlerts;
            color += "rgb(255, 165, 0);";
            break;
        default:
            return;
        }

        int val = lcd->intValue();
        lcd->display(val + 1);
        lcd->setStyleSheet(QString::fromStdString(color));
    }
}

} /* namespace ui */
